package net.zoneland.zrdp.common.utils;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 时间工具类
 *
 * @author zonevue
 */
public class DateUtil extends DateUtils {
    private DateUtil() {
        // Do nothing
    }

    private static final String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    // 日期转字符串 yyyy/MM/dd
    public static final DateTimeFormatter DATE_FORMATTER_SLASHED_YYYYMMDD = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    // 日期转字符串 yyyyMMdd
    public static final DateTimeFormatter DATE_FORMATTER_YYYYMMDD = DateTimeFormatter.ofPattern("yyyyMMdd");


    // 日期转字符串 yyyy-MM-dd
    public static final DateTimeFormatter DATE_FORMATTER_DASHED_YYYYMMDD = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    // 日期转字符串 yyyy-MM-dd HH:mm:ss
    public static final DateTimeFormatter DATE_FORMATTER_DASHED_YYYYMMDD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 日期转字符串 yyyyMMddHHmmss
    public static final DateTimeFormatter DATE_FORMATTER_YYYYMMDDHHMMSS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    public static LocalDateTime getNowLocalDateTime() {
        return LocalDateTime.now();
    }
    /**
     * 获取当前月份 1-12
     * @return 月份数字
     */
    public static int getMonth(){
        final LocalDate localDate = LocalDate.now();
        return localDate.getMonthValue();
    }
    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return DATE_FORMATTER_DASHED_YYYYMMDD.format(LocalDate.now());
    }
    /**
     * 获取当前日期和时间, 默认格式为yyyy-MM-dd HH:mm:ss
     *
     * @return String
     */
    public static String getTime() {
        return DATE_FORMATTER_DASHED_YYYYMMDD_HH_MM_SS.format(LocalDateTime.now());
    }

    public static String dateTimeNow() {
        return DATE_FORMATTER_YYYYMMDDHHMMSS.format(LocalDateTime.now());
    }

    /**
     * 日期格式化
     */
    public static String parseDateToStr(final String format, final Date date) {
        final FastDateFormat fdf = FastDateFormat.getInstance(format);
        return fdf.format(date);
    }

    public static String parseLocalDateTimeToStr(final LocalDateTime date) {
        return DATE_FORMATTER_DASHED_YYYYMMDD_HH_MM_SS.format(date);
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static String datePath() {
        return DATE_FORMATTER_SLASHED_YYYYMMDD.format(LocalDate.now());
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static String getDateYMD() {
        return DATE_FORMATTER_YYYYMMDD.format(LocalDate.now());
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static LocalDateTime getServerStartDate() {
        final long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return Instant.ofEpochMilli(time).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
    }

    /**
     * 计算时间差
     *
     * @param endTime 最后时间
     * @param startTime 开始时间
     * @return 时间差（天/小时/分钟）
     */
    public static String timeDistance(LocalDateTime endTime, LocalDateTime startTime) {
        final Duration duration = Duration.between(startTime, endTime);

        final long days = duration.toDays();
        final long hours = duration.toHours() - (days * 24);
        final long minutes = duration.toMinutes() - (days * 24 * 60) - (hours * 60);

        return days + "天" + hours + "小时" + minutes + "分钟";
    }
    /**
     * 增加 Date ==> LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(final Date date) {
        if(date == null){
            return null;
        }
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
    }

    public static LocalDateTime longToLocalDateTime(final Long date) {
        if(date == null){
            return null;
        }
        return Instant.ofEpochMilli(date).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
    }

    /**
     * 增加 LocalDateTime ==> Date
     */
    public static Date localDateTimetoDate(final LocalDateTime temporalAccessor) {
        final ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.of("Asia/Shanghai"));
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date localDatetoDate(final LocalDate temporalAccessor) {
        final Instant instant = temporalAccessor.atStartOfDay().atZone(ZoneId.of("Asia/Shanghai")).toInstant();
        return Date.from(instant);
    }
}
